package link;


import org.junit.Test;

//约瑟夫  单向环形链表  1<=k<=n  从k开始报数 m是数几下，数到谁 谁出列，以此类推，由此产生一个出队编号的序列
public class Josepfu {
    @Test
      public void test(){
        CircleSingleList list=new CircleSingleList();
        list.addBoys(5);
        list.showBoys();
        // 2 ->4 ->1->5->3
        list.countBoy(1, 2, 5);
    }
}

class CircleSingleList{

    Boy first=null;//定义一个first指针 不能动，给我们定位来用
    //添加小孩
    public  void addBoys(int m){
        if(m<1) {
            System.out.println("输入的值错误！");
            return;
        }
        Boy curBoy=null; //定义一个辅助指针遍历  帮助我们实现环形链表
        for (int i =1; i <=m; i++) {
            Boy boy=new Boy(i);
            if(i==1){ //如果是第一个小孩
                first=boy;
                first.next=first; //构成环
                curBoy=first; //让curBoy 指向第一个小孩
            }else {
                curBoy.next=boy;
                boy.next=first;
                curBoy=boy;
            }
        }

    }
    //遍历链表
    public  void showBoys(){
        Boy curBoy=first;
        if(first==null){
            System.out.println("没有小孩~~~");
            return;
        }
        while(true){
            System.out.println("小孩的编号:"+curBoy.no);
            if(curBoy.next==first){ //已经遍历完毕
                break;
            }
            curBoy=curBoy.next;
        }


    }

    //根据用户的输入，计算出小孩出圈的顺序
    public void countBoy(int startNo,int countNum,int nums){
            //先对数据进行校验
        if(first==null||startNo<1||startNo>nums){
            System.out.println("参数输入有误");
            return;
        }
        Boy helper=first; //创建辅助指针，帮助小孩出圈
        while (true){
            if(helper.next==first){ //helper移动到小孩的最后节点
                break;
            }
            helper=helper.next;
        }
        //小孩报数前，先让first,helper移动startNo-1次
        for (int i = 0; i <startNo-1; i++) {
            first=first.next;
            helper=helper.next;
        }
        //当小孩报数时候，先让first,helper移动countNum-1次
        while(true){
            if(helper==first){ //说明只有最后一个小孩
                break;
            }
            for (int i = 0; i <countNum-1 ; i++) {
                first=first.next;
                helper=helper.next;
            }
            System.out.println("出圈的小孩编号:"+first.no);
            //删除出圈的小孩
            first=first.next;
            helper.next=first;
        }
        System.out.println("最后一个小孩的编号是:"+first.no);

    }
}



//定义一个小孩节点
class Boy {
    int no;
    Boy next;  //默认是null

    public Boy() {
    }

    public Boy(int no) {
        this.no = no;
    }

    @Override
    public String toString() {
        return "Boy{" + "no=" + no + "}";
    }
}
